package main

import (
	"fmt"

	"gitee.com/jnshao/go-start/basic/oop"
)

// 定义别名的方式扩展类型
// go语言无继承，达到继承的用法
type myTreeNode struct {
	node *oop.Node //使用其他包中类型，包名.类型名
}

func (myNode *myTreeNode) postOrder() {
	if myNode == nil || myNode.node == nil {
		return
	}

	left := myTreeNode{myNode.node.Left}
	right := myTreeNode{myNode.node.Right}

	//postOrder接收者为指针，left是结构提本身，可以调用必须定义变量.访问不然报错
	//myTreeNode{myNode.node.Left}.postOrder()会编译不通过
	left.postOrder()
	right.postOrder()
	myNode.node.Print()
}

// 结构体 值/指针接收者方法均可接收值/指针(结构体本身或指针均能调用值/指针接收者方法)
func main() {
	//直接使用{}，创建结构体
	root := oop.Node{Value: 3}
	//go语言中不管是指针还是结构实例一律使用.访问成员
	root.Left = &oop.Node{}
	root.Right = &oop.Node{5, nil, nil}
	//使用内置函数new，创建空结构体地址
	root.Right.Left = new(oop.Node)
	//加工厂函数创建，类似构造函数
	root.Left.Right = oop.CreateNode(2)
	//成员属性赋值
	root.Right.Left.SetValue(4)

	//结构体数组创建
	nodes := []oop.Node{
		{Value: 3},
		{},
		{6, nil, &root},
	}
	fmt.Println(nodes)

	fmt.Print("In-order traversal: ")
	root.Traverse()

	fmt.Print("My own post-order traversal: ")
	myRoot := myTreeNode{&root}
	myRoot.postOrder()
	fmt.Println()

	nodeCount := 0
	root.TraverseFunc(func(node *oop.Node) { //输出节点数
		nodeCount++
	})
	fmt.Println("Node count:", nodeCount)

	c := root.TraverseWithChannel()
	maxNodeValue := 0
	for node := range c {
		if node.Value > maxNodeValue {
			maxNodeValue = node.Value
		}
	}
	fmt.Println("Max node value:", maxNodeValue)
}

// Integer 衍生类型,可以相互转换，但也是全新类型，主要为了扩展原类型的方法
type Integer int

// 别名， 就是同一个类型，主要为了兼容
type integer = int
